﻿using System;
using System.Collections.Generic;
using System.Linq;
using AutoMock.Frameworks;

namespace AutoMock
{
    /// <summary>
    /// 
    /// </summary>
    /// <typeparam name="T">Type of class to test and create an instance of.</typeparam>
    public class AutoMocker<T, TMockFramework>
        where T : class
    {
        private Dictionary<Type, object> _mocks;
        private IMockingFrameworkProvider<TMockFramework> _framework;
        private readonly object[] _constructorDependencys;
        private T _classUndertest;

        public T ClassUnderTest
        {
            get
            {
                return _classUndertest ?? (_classUndertest = InstanceCreator<T>.CreateInstance(_mocks.Values.ToArray()));
            }
        }

        public AutoMocker(IMockingFrameworkProvider<TMockFramework> framework, params object[] constructorDependencys)
        {
            if (typeof(T).IsInterface) throw new Exception("Interface cannot be used as ClassUnderTest. Only concrete class implementations are supported.");

            _framework = framework;
            _constructorDependencys = constructorDependencys;

            _mocks = MocksCreator<T, TMockFramework>.CreateMocks(_framework, _constructorDependencys);
            
        }

        public TMock Get<TMock>()
        {
            if (!_mocks.ContainsKey(typeof(TMock)))
                throw new Exception("The given type was not found.");

            return (TMock)_mocks[typeof(TMock)];
        }

        public TMockFramework Repository { get { return _framework.Repository; } }
    }
}
